package com.lightsh.md5;

import java.io.File;
import java.io.FileInputStream;
import java.security.MessageDigest;

import android.util.Log;

public class Md5Utility {
	private static final String TAG = "Md5Utility";
	
	
	private final static String[] hexDigits = { "0", "1", "2", "3", "4", "5",
			"6", "7", "8", "9", "a", "b", "c", "d", "e", "f" };
	/**
	 * 
	 * 描述：转换字节数组为16进制字串
	 * 
	 */
	public static String byteArrayToHexString(byte[] b) {
		StringBuffer resultSb = new StringBuffer();
		for (int i = 0; i < b.length; i++) {
			resultSb.append(byteToHexString(b[i], true));
		}
		return resultSb.toString();
	}

	public static String byteArrayToHexString(byte[] b, int beginPos, int length) {
		StringBuffer resultSb = new StringBuffer();
		for (int i = beginPos; i < length + beginPos; i++) {
			resultSb.append(byteToHexString(b[i], true));
		}
		return resultSb.toString();
	}

	public static String byteArrayToHexStringLittleEnding(byte[] b) {
		StringBuffer resultSb = new StringBuffer();
		for (int i = 0; i < b.length; i++) {
			resultSb.append(byteToHexString(b[i], false));
		}
		return resultSb.toString();
	}

	private static String byteToHexString(byte b, boolean bigEnding) {
		int n = b;
		if (n < 0)
			n = 256 + n;
		int d1 = n / 16;
		int d2 = n % 16;
		return (bigEnding) ? (hexDigits[d1] + hexDigits[d2])
				: (hexDigits[d2] + hexDigits[d1]);
	}

	public static String MD5Encode(String origin) {
		return MD5Encode(origin, null);
	}

	/**
	 * 把16进制字符串转换为byte数组
	 */
	public static byte[] hexStringToByteArray(String s) {
		if (s.length() % 2 != 0) {
			throw new RuntimeException("Error Hex String length");
		}
		byte[] result = new byte[s.length() / 2];
		for (int i = 0; i < s.length();) {
			int bytepos = i / 2;
			char c = s.charAt(i++);
			char c2 = s.charAt(i++);
			result[bytepos] = Integer.decode("0x" + c + c2).byteValue();
		}
		return result;
	}

	public static String MD5Encode(String origin, String encoding) {
		String resultString = null;

		try {
			resultString = new String(origin);
			MessageDigest md = MessageDigest.getInstance("MD5");
			if (encoding == null) {
				resultString = byteArrayToHexString(md.digest(resultString
						.getBytes()));
			} else {
				resultString = byteArrayToHexString(md.digest(resultString
						.getBytes(encoding)));
			}

		} catch (Exception e) {
			throw new RuntimeException(e);
		}

		return resultString;
	}

	public static byte[] MD5Encode(byte origin[]) {
		try {
			MessageDigest md = MessageDigest.getInstance("MD5");
			return md.digest(origin);
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}
	public static String getFileMd5String(String filePath){
		byte[] result = getFileMd5(filePath);
		if(result != null){
			return byteArrayToHexString(result);
		}
		return null;		
	}
	
	public static byte[] getFileMd5(String filePath){
		File hFile = new File(filePath);
		if(hFile.exists()){
			try {
				FileInputStream iStream = new FileInputStream(hFile);
				try{
					MessageDigest md = MessageDigest.getInstance("MD5");
					byte[] buffer = new byte[4096];
					while(true){
						int len = iStream.read(buffer);
						if(len<0){
							break;
						}
						md.update(buffer,0,len);
					}  
					return md.digest();
				}finally{
					iStream.close();
				}				
			} catch (Exception e) {
				Log.w(TAG, "md5 exception:" + e.getMessage());
				return null;
			}
		}else{
			Log.w(TAG, "file not exist");	
			return null;
		}
	}
}
